iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0
自我挑戰組

Django 初學入門 - 從 ROR 的角度來學習 Django系列 第 29

DAY29 - Django 登入權限驗證

  • 分享至 

  • xImage
  •  

我們前面做好 註冊/登入 系統了,那當然要來測試一下,限制一些頁面只有登入以後才能進入拉~

登入權限的設定有分兩種,一種是我們在 views.py 自訂的 基礎函式,像是我們首頁 def index,另一種就是我們使用 Django 提供的版本,像是我們老闆列表頁 EmployerListView,這兩種限制登入權限瀏覽的設定是不一樣的

基礎函式 def index

首先我們看一下 基礎函式 def index 的設定方式:

from django.contrib.auth.decorators import login_required

@login_required
def index(request):
    # ...省略

這邊說明一下上面在幹嘛,@login_required 是一個 Django 裝飾器(decorator),裝飾器用於修改或擴展 views 的行為。今天這樣設定,@login_required 裝飾器用於限制訪問特定 views 的使用者必須處於已登入狀態,否則他們將被重導到登入頁面。

白話文就是,當我今天在 index 上方加上 @login_required,之後你進到對應的網址,也就是 http://127.0.0.1:8000/online/,他會因為你設定登入權限的關係,自動轉跳到 http://127.0.0.1:8000/accounts/login/?next=/online/ 登入頁面

https://ithelp.ithome.com.tw/upload/images/20231010/20162365sTT2AQVkh8.png

模版函示 EmployerListView

那如果今天是這一種 EmployerListView,是由 Django 提供的 模版函示 要怎麼設定呢?只要像這樣設定就好:

from django.contrib.auth.mixins import LoginRequiredMixin

class EmployerListView(LoginRequiredMixin, generic.ListView):
    model = Employer

這個模板權限設定的效果跟 @login_required ˊ一樣,只要這樣設定後,當你進入 http://127.0.0.1:8000/online/employers/,他就會自動轉跳到 http://127.0.0.1:8000/accounts/login/?next=/online/employers/ 登入頁面

https://ithelp.ithome.com.tw/upload/images/20231010/20162365gXc2GNzbKq.png

客製化驗證

如果今天想要客製化一種驗證,也可以做到,首先我們先看一下這一張圖:

https://ithelp.ithome.com.tw/upload/images/20231010/20162365ixgj8gekHW.png

這個畫面是 admin 後台的調整使用者權限的地方,目前可以看到 Store 的權限有四個 addchangedeleteview,就是基本的 CRUD,我們現在來針對 Store 增加一種權限

model 調整

我們在 modelStore 地方加上 Meta permissions,我們用 tuple 包住他們,左邊是驗證的名稱,右邊是驗證的值(聽不懂沒關係,等等會實作)

# store/online/models.py

class Store(models.Model):
    # ...省略

    class Meta:        
        permissions = (("can_mark_store", "Set store as noticed"),)    

具現化

這邊調整完後,記得具現化表單

$ python3 manage.py makemigrations

------
Migrations for 'online':
  online/migrations/0004_alter_store_options.py
    - Change Meta options on store    
$ python3 manage.py migrate

------
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, online, sessions
Running migrations:
  Applying online.0004_alter_store_options... OK

具現化好後,我們再打開 admin 的後台,到調整使用者權限的地方看,應該會如下圖:

https://ithelp.ithome.com.tw/upload/images/20231010/20162365kxVkP5BuNm.png

會發現多了一個 Set store as noticed 的權限設定,而這個名字就是我們剛剛在 Meta permissions 中增加的值

views 設定

新增好值後,接著我們到 views 的地方來設定是否可以瀏覽特定頁面

# online/views.py

from django.contrib.auth.mixins import PermissionRequiredMixin

class StoreListView(PermissionRequiredMixin, generic.ListView):
    model = Store
    permission_required = 'online.can_mark_store'
    raise_exception = True  # 如果用戶沒有權限,引發PermissionDenied異常    

我們在 StoreListView 這個 Django 客製化的 listView 修改成這樣,解釋一下上面在幹嘛:

  1. 首先我們引用 PermissionRequiredMixin這個東西是使用客製化權限設定時候用的的參數
  2. StoreListView 引入該參數,permission_required後面的字串是 應用程式.客製權限名稱,因此是 online.can_mark_storecan_mark_store 這個就是我們在 Meta permissions 中新增的名稱
  3. 如果用戶沒有權限,就引發錯誤

templates

最後就是在 StoreListView 對應的連結 http://127.0.0.1:8000/online/stores/ 測試驗證結果拉 :

<!-- store/online/templates/online/store_list.html -->
{% extends 'sidebar.html' %}

{% block content %}

  {% if perms.online.can_mark_store %}
    <p>你有權限的話看得到我</p>
  {% endif %}

  <!-- ...省略 -->
{% endblock %}  

可以看到下圖,因為我這個帳號是最高權限,所以基本上所有訊息都看得到:

https://ithelp.ithome.com.tw/upload/images/20231010/2016236564Gf905S3W.png

perms 是什麼

在Django中,perms(也稱為權限)是一種機制,用於控制哪些使用者(user)或群組(group)可以執行特定操作或訪問特定資源。Django的權限系統允許你精細地控制你的應用程式中的瀏覽權限:

如果不懂的話,我們直接把 perms 印出來看,你就知道了:

<!-- store/online/templates/online/store_list.html -->
{% extends 'sidebar.html' %}

{% block content %}

  <!-- ...省略 -->
  {{ perms }}
  <br>  
  {{ perms.online }}

  <!-- ...省略 -->
{% endblock %}  

可以發現我們印出來,他會顯示你現在的帳號有哪些權限,可以依照擁有的權限來做特定的事情

https://ithelp.ithome.com.tw/upload/images/20231010/20162365Fyj7HwuKUk.png

實際應用

剛剛上面如果聽不懂的話,可以直接來看應用方式,由於剛剛因為是超級使用者,所以他可以進入所有頁面、看到所有的文字,那我們現在改成,一個使用者有瀏覽 store-list 也就是瀏覽 http://127.0.0.1:8000/online/stores/ 連結的權限,但是沒有 can_mark_store 的權限,因此這個使用者進到 http://127.0.0.1:8000/online/stores/ 頁面後,看不到 你有權限的話看得到我 這一段字。

views.py 權限修改

首先把 StoreListView 這個 class 的權限改成要有 view_store 權限才能進入

class StoreListView(PermissionRequiredMixin, generic.ListView):
    model = Store    
    permission_required = ('online.view_store')    
    raise_exception = True  # 如果用戶沒有權限,引發PermissionDenied異常    

admin 調整使用者權限

接著我們開一個新的使用者,此使用者沒有最高權限,我們實際測試使用者名稱為 - test1234 的使用者,我們把他的權限增加 online | store | Can view store,如下圖:

https://ithelp.ithome.com.tw/upload/images/20231010/20162365kN3JqcuXQN.png

templates 修改

接著來看我們的 templates 頁面,不過其實不用修改,因為我們前面已經加上條件限制 if perms.online.can_mark_store,要有 mark_store 的權限才能看到這一行字,因此你看到的圖會長這樣:

https://ithelp.ithome.com.tw/upload/images/20231010/20162365qQcTfIJZZy.png

少了 你有權限的話看得到我 這一段字,並且 perms.online 印出的權限只有 {'online.view_store'},這樣看完之後應該就很清楚了!

這樣我們就詳細說明了 Django 的 登入 / 註冊 / 權限 要如何使用~

總結

今天學到哪些東西呢?

  1. Django 的權限設定
  2. Django 如何自訂權限
  3. Django 的 perms 是什麼

最後附上 Github: https://github.com/eagle0526/Django-store


上一篇
DAY28 - Django 登入系統 - 3
下一篇
DAY30 - 介紹 Django 進階的 url 設定 + 結語
系列文
Django 初學入門 - 從 ROR 的角度來學習 Django30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言